package cn.italkcloud.cph.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @author dominate
 * @since 2022/12/16
 */
public final class JsonUtil {
    private static final String EMPTY_STRING = "";


    public static <T> T parse(String json, Class<T> tClass) {
        JSONObject resultJson = JSONObject.parseObject(json);
        return resultJson.toJavaObject(tClass);
    }

    public static <T> T parse(String json, Class<T> tClass, String... keys) {
        JSONObject resultJson = JSONObject.parseObject(json);
        for (int i = 0; i < keys.length; i++) {
            if (keys.length - 1 == i) {
                return resultJson.getJSONObject(keys[i]).toJavaObject(tClass);
            }
            resultJson = resultJson.getJSONObject(keys[i]);
        }
        return resultJson.toJavaObject(tClass);
    }

    public static <T> List<T> parseToList(String json, Class<T> tClass, String... keys) {
        if (isEmpty(json)) {
            return Collections.emptyList();
        }
        JSONArray data = parseToJsonArray(json, keys);
        return parseToList(data, tClass);
    }

    public static <T> List<T> parseToList(JSONArray data, Class<T> tClass) {
        if (data == null) {
            return Collections.emptyList();
        }
        List<T> resultList = new ArrayList<>(data.size());
        for (int i = 0; i < data.size(); i++) {
            resultList.add(JSONObject.toJavaObject(data.getJSONObject(i), tClass));
        }
        return resultList;
    }


    public static Object parseToObj(String json, String... keys) {
        JSONObject resultJson = JSONObject.parseObject(json);
        for (int i = 0; i < keys.length; i++) {
            if (keys.length - 1 == i) {
                return resultJson.get(keys[i]);
            }
            resultJson = resultJson.getJSONObject(keys[i]);
        }
        return resultJson;
    }

    public static JSONArray parseToJsonArray(String jsonResponse, String... keys) {
        if (keys.length == 0) {
            return JSONObject.parseArray(jsonResponse);
        }
        JSONObject resultJson = JSONObject.parseObject(jsonResponse);
        for (int i = 0; i < keys.length; i++) {
            if (keys.length - 1 == i) {
                return resultJson.getJSONArray(keys[i]);
            }
            resultJson = resultJson.getJSONObject(keys[i]);
        }
        return JSONObject.parseArray(jsonResponse);
    }

    public static JSONObject parseResponseValueForJsonObject(String jsonResponse, String... keys) {
        JSONObject resultJson = JSONObject.parseObject(jsonResponse);
        for (int i = 0; i < keys.length; i++) {
            if (keys.length - 1 == i) {
                return resultJson.getJSONObject(keys[i]);
            }
            resultJson = resultJson.getJSONObject(keys[i]);
        }
        return resultJson;
    }

    public static String parseToString(String jsonResponse, String... keys) {
        JSONObject resultJson = JSONObject.parseObject(jsonResponse);
        for (int i = 0; i < keys.length; i++) {
            if (keys.length - 1 == i) {
                return resultJson.getString(keys[i]);
            }
            resultJson = resultJson.getJSONObject(keys[i]);
        }
        return resultJson.toString();
    }

    public static Boolean parseToBoolean(String jsonResponse, String... keys) {
        JSONObject resultJson = JSONObject.parseObject(jsonResponse);
        for (int i = 0; i < keys.length; i++) {
            if (keys.length - 1 == i) {
                return resultJson.getBoolean(keys[i]);
            }
            resultJson = resultJson.getJSONObject(keys[i]);
        }
        return Boolean.parseBoolean(resultJson.toString());
    }


    public static <T> Map<String, T> jsonToMap(String json, Type type) {
        return JSON.parseObject(json, type);
    }

    private static boolean isEmpty(Object str) {
        return str == null || EMPTY_STRING.equals(str);
    }
}
